package edu.intprog.egreeting;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import edu.intprog.mail.ActivationMailer;
import edu.intprog.mail.BaseMailer;
import edu.intprog.sql.SessionManager;
import edu.intprog.egreeting.basic.EgreetingBaseServlet;
import edu.intprog.egreeting.beans.Messages;
import edu.intprog.egreeting.beans.UserDef;

/**
 * Servlet implementation class for Servlet: RegistrationServlet
 *
 */
 public class RegistrationServlet extends EgreetingBaseServlet implements javax.servlet.Servlet {
   static final long serialVersionUID = 1L;
   
    /* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	public RegistrationServlet() {
		super();
	}   	 	
	
	/**
	 * doPost
	 * 
	 * this function will receive new account information, add it to the DB if it validates
	 * and send an activation mail to the user.
	 * 
	 * activation links which are embedded in the sent mail are handled by the doGet function
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		if (request.getParameter("cancel")!=null)
		{
			//cancel was pressed
			getServletContext().getRequestDispatcher("/StartServlet").forward(request, response);
			return;
		}
		
		//update the user definition from the request parameters
		UserDef newUser = new UserDef();
		newUser.set_fName(request.getParameter("fName"));
		newUser.set_lName(request.getParameter("lName"));
		newUser.set_emailAddr(request.getParameter("emailAddr"));
		newUser.set_phoneNumber(request.getParameter("phoneNumber"));
		newUser.set_userPassword(request.getParameter("userPassword"));
		newUser.set_userPassword2(request.getParameter("userPassword2"));

		//validate the user fields
		String validationResult = newUser.validate();
		
		Transaction tx = null;
		Session session = SessionManager.getCurrentSession();
		try {
			tx = session.beginTransaction();
			Query query = session.createQuery("from edu.intprog.egreeting.beans.UserDef where EMAIL_ADDR=:eMail");
			query.setString("eMail", newUser.get_emailAddr());
			@SuppressWarnings("unchecked")
			List<UserDef> result = (List<UserDef>) query.list();
			tx.commit();
			if(result.size()>0)
			{
				//email address is aleady in the DB
				validationResult = validationResult + "E-Mail address is already known. If this is your E-Mail address, be to sure that you have activated your account.\n";
			}
		} catch (HibernateException e) {
			e.printStackTrace();
			if (tx != null && tx.isActive())
				tx.rollback();
			//sql error
			validationResult = validationResult + e.getMessage() + "<br />";
		}
		
		if (validationResult.length() > 0)
		{
			//some error was detected - report it to the user
			Messages error = new Messages();
			error.set_errorMessage(validationResult);
			request.setAttribute("msgs", error);
			getServletContext().getRequestDispatcher("/registrationPage.jsp").forward(request, response);
		}
		else
		{
			//no errors - the new user definition can be added
			try {
				session = SessionManager.getCurrentSession();
				tx = session.beginTransaction();
				session.save(newUser);
				tx.commit();
				BaseMailer.initilizeMailConfigurationFromFile(request);
				ActivationMailer am = new ActivationMailer(newUser.get_emailAddr());
				validationResult = am.sendMail(request.getRequestURL().toString());
				if (validationResult.length() > 0)
				{
					session = SessionManager.getCurrentSession();
					tx = session.beginTransaction();
					session.delete(newUser);
					tx.commit();
				}
			} catch (HibernateException e) {
				e.printStackTrace();
				if (tx != null && tx.isActive())
					tx.rollback();
				//sql error
				validationResult = validationResult + e.getMessage() + "<br />";
			}
			
			if (validationResult.length() > 0)
			{
				//report error to the user
				Messages error = new Messages();
				error.set_errorMessage(validationResult);
				request.setAttribute("msgs", error);
			}
			
			// forward the request to the jsp
			getServletContext().getRequestDispatcher("/StartServlet").forward(request, response);
		}
	}

	/**
	 * doGet
	 * 
	 * this function handle links from activation mails
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String userEmail = request.getParameter(ActivationMailer._emailAddrParamName);
		if (userEmail==null)
		{
			getServletContext().getRequestDispatcher("/StartServlet").forward(request, response);
			return;
		}
		
		//set the user as active
		Transaction tx = null;
		Session session = SessionManager.getCurrentSession();
		tx = session.beginTransaction();
		Query query = session.createQuery("update edu.intprog.egreeting.beans.UserDef set _isActive = true where _emailAddr = :email and _isActive = false");
		query.setString("email",userEmail);
		int rowCount = query.executeUpdate();
		tx.commit();
		
		String message = new String();
		Messages error = new Messages();
		
		if (rowCount == 1)
		{
			//email was activated successfully
			message = "E-Mail was activated successfully.<br/>";
			error.set_infoMessage(message);
		}
		else
		{
			//email was not pending activation
			message = "E-Mail is not pending activation.<br/>";
			error.set_errorMessage(message);
		}

		request.setAttribute("msgs", error);
		getServletContext().getRequestDispatcher("/StartServlet").forward(request, response);
	}
}